using System.Collections.Generic;
using JetBrains.ReSharper.Daemon.Stages;
using JetBrains.ReSharper.Psi.CSharp.Tree;
using Twins.Daemon;
using Twins.Infrastructure;
using Twins.Interface;
using Twins.Interface.IProcesser;

namespace Twins.Classes
{
    public class LookCSharpFile : ILookCSharpFile
    {
        private readonly ICodeExecutor codeExecutor;
        private readonly ITwinsHighLighting twinsHighLighting;

        public LookCSharpFile(ICodeExecutor codeExecutor, ITwinsHighLighting twinsHighLighting)
        {
            this.codeExecutor = codeExecutor;
            this.twinsHighLighting = twinsHighLighting;
        }

        public List<IHashsLineCodeMethod> StartLook(IHighlightingConsumer highlightingConsumer, ICSharpFile cSharpFile)
        {
            var hashsLineCodeMethods = new List<IHashsLineCodeMethod>();

            foreach (ICSharpNamespaceDeclaration cSharpNamespaceDeclaration in cSharpFile.NamespaceDeclarations)
            foreach (IClassDeclaration cSharpTypeDeclaration in cSharpNamespaceDeclaration.TypeDeclarations)
            foreach (IMethodDeclaration method in cSharpTypeDeclaration.MethodDeclarations)
                if (method.Body != null)
                {
                    var hashsLineCodeMethod = new HashsLineCodeMethod();
                    foreach (ICSharpStatement statement in method.Body.Statements)
                    {
                        var processerCSharpStatement = IoC.Resolve<IProcesser>("ProcesserCSharpStatement"); 
                        var lineCodeMethod = processerCSharpStatement.DoSomethingWith(statement);
                        if (lineCodeMethod == null) continue;
                        foreach (var lineCode in lineCodeMethod)
                        {
                            string hashLineCode = codeExecutor.GetHashLineCode(new Md5CodeOperation(),
                                                                               lineCode.HashLineCode);
                            hashsLineCodeMethod.AddLineCode(new LineCode(lineCode.Statement, hashLineCode));
                        }
                    }
                    twinsHighLighting.UnderlineDuplication(hashsLineCodeMethod.DuplicationHashsLineCode, highlightingConsumer);
                    hashsLineCodeMethods.Add(hashsLineCodeMethod);
                }
            return hashsLineCodeMethods; 
        }
    }
}